import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.io.FileUtils;

/**
 * @description 随机爬取百度经验
 * 把class文件和mysql驱动放到同一个目录下上传linux
 * nohup java -Djava.ext.dirs=. -classpath . Launch >> baidu_jingyan.log &
 * @author zhaominglei
 * @date 2016年3月29日
 */
public class Launch {
	private static final int TIMEOUT_IN_MILLIONS = 60*1000;
	public static final Integer COUNTS_DEFAULT = 10; //读取不到配置文件用这个
	public static Integer COUNTS;
	public static void main(String[] args) {
//		Launch launch = new Launch();
//		for (int i = 0; i < COUNTS; i++) {
//			launch.randomAndSnatch();
//		}
//		launch.randomAndSnatch();
		try {
			String count = FileUtils.readFileToString(new File(new URI(Launch.class.getResource("/")+"counts.txt")));
			if (count != null && !count.equals("")) {
				COUNTS = Integer.valueOf(count);
			} else {
				COUNTS = COUNTS_DEFAULT;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		Timer timer = new Timer();
		TimerTask timerTask = new TimerTask() {
			@Override
			public void run() {
				Launch launch = new Launch();
				for (int i = 0; i < COUNTS; i++) {
					launch.randomAndSnatch();
					try {
						Thread.sleep(new Random().nextInt(60)*1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		timer.schedule(timerTask, new Date(), 1000*60*60*24);
	}
	
	public void randomAndSnatch() {
		List<Jingyan> jingyans = getJingyans();
		if (jingyans != null && !jingyans.isEmpty()) {
			Jingyan jingyan = jingyans.get(new Random().nextInt(jingyans.size()));
			if (jingyan != null && jingyan.getTitle() != null && !jingyan.getTitle().equals("")) {
				String html = doGetForJingyan(jingyan.getUrl(), jingyan.getTitle(), null);
//				System.out.println(jingyan.getTitle()+"=>"+html);
				System.out.println(getDateTime("yyyy-MM-dd HH:mm:ss", new Date())+" : "+jingyan.getTitle()+" => +1");
				if (html != null) {
					String sql = "update jingyan set view_count=view_count+1 where id ="+jingyan.getId();
					saveBysql(sql);
				}
			}
		}
	}
	public Connection getConnection() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Connection connection = DriverManager.getConnection("jdbc:mysql://118.126.13.114:33060/baidu?useUnicode=true&characterEncoding=UTF-8", "baidu", "baidu_+-=");
			return connection;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	public void saveBysql(String sql) { //values 格式('http://better.apps.cn',1,'appnames'),('http://better.apps.cn',1,'appnames')
		Connection connection = getConnection();
		try {
			connection.setAutoCommit(false);
			Statement stmt = connection.createStatement();
			stmt.execute(sql);
			connection.commit();
		} catch (SQLException e) {
			try {
				connection.rollback(); //不要忘记
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	public List<Jingyan> getJingyans() {
		List<Jingyan> jingyans = new ArrayList<Jingyan>();
		Connection connection = getConnection();
		try {
			Statement stmt = connection.createStatement();
			ResultSet rs = stmt.executeQuery("select * from jingyan");
			while (rs.next()) {
				Jingyan jingyan = new Jingyan();
				jingyan.setId(rs.getLong("id"));
				jingyan.setTitle(rs.getString("title"));
				jingyan.setUrl(rs.getString("url"));
				jingyan.setViewCount(rs.getInt("view_count"));
				jingyans.add(jingyan);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return jingyans;
	}	
	public static final String getDateTime(String aMask, Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";
		if (aDate == null) {
		} else {
			df = new SimpleDateFormat(aMask);
			returnValue = df.format(aDate);
		}
		return (returnValue);
	}
	/**
	 * Get请求，获得返回数据
	 */
	public static String doGetForJingyan(String urlStr, String keyword, String charsetName) {
		charsetName = (charsetName == null || charsetName.equals("")) ? "UTF-8" : charsetName;
		URL url = null;
		HttpURLConnection conn = null;
		InputStream is = null;
		ByteArrayOutputStream baos = null;
		try {
			url = new URL(urlStr);
			conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
			conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Accept", "*/*");
			conn.setRequestProperty("Referer", "http://jingyan.baidu.com/search?word="+encodeURI(keyword));
			conn.setRequestProperty("Accept-Language", "zh-cn");
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
			conn.setRequestProperty("Host", "jingyan.baidu.com");
			conn.setRequestProperty("Connection", "Keep-Alive");
			String PMS_JT = encodeURI("({\"s\":1459298876729,\"r\":\"http://jingyan.baidu.com/search?word="+encodeURI(keyword)+"\"})");
			conn.setRequestProperty("Cookie", "BAIDUID=853D4C991C50FF888DEE8FA2A523D07A:FG=1; BIDUPSID=DEB6D0702BEA7FF8B36BD054CE032D86; PSTM=1458814109; PS_REFER=0; Hm_lvt_46c8852ae89f7d9526f0082fafa15edd=1459217273; bdshare_firstime=1428748974328; PMS_JT="+PMS_JT);
			
			if (conn.getResponseCode() == 200) {
				is = conn.getInputStream();
				baos = new ByteArrayOutputStream();
				int len = -1;
				byte[] buf = new byte[1024];

				while ((len = is.read(buf)) != -1) {
					baos.write(buf, 0, len);
				}
				baos.flush();
				return baos.toString(charsetName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
				if (baos != null) {
					baos.close();
				}
			} catch (IOException e) {
			}
			conn.disconnect();
		}
		return null;
	}
	public static String encodeURI(String str) {
		String s=str;
		if(s==null || s.equals("")) return s;
		try {
			s=URLEncoder.encode(str, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return s;
	}	
}

class Jingyan implements Serializable{
	private static final long serialVersionUID = 6005352724489947501L;
	private Long id; //主键
	private String title; //标题
	private String url; //地址
	private Integer viewCount; //浏览次数
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public Integer getViewCount() {
		return viewCount;
	}
	public void setViewCount(Integer viewCount) {
		this.viewCount = viewCount;
	}
}
